%% class_record_common.erl
%%   Common operations on classes and records.
%%
%% Copyright (C) 2008, 2009 Gábor Fehér
%%
%% This file is part of ECT.
%% 
%% ECT is free software: you can redistribute it and/or modify
%% it under the terms of the GNU General Public License as published by
%% the Free Software Foundation, either version 3 of the License, or
%% (at your option) any later version.
%% 
%% ECT is distributed in the hope that it will be useful,
%% but WITHOUT ANY WARRANTY; without even the implied warranty of
%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
%% GNU General Public License for more details.
%% 
%% You should have received a copy of the GNU General Public License
%% along with ECT.  If not, see <http://www.gnu.org/licenses/>.
%%
-module(class_record_common).
-export([field_accessor/5, get_definition/3]).

-include("common_defs.hrl").

%% Function: field_accessor(Definition, FieldName, RecExpr, CxClass, Line)
%% Purpose: returns an AST fragment that can be used to access a field of an object or record
%% Arguments:
%%   Definition::#class{} | {record, Name, Fields} - definition of the class or record
%%   FieldName::atom() - name of field
%%   RecExpr - an expression in AST form that is the object/record, whose field is accessed
%%   CxClass::atom() - name of class from where the field is accessed, or none
%%   Line::integer() - line number to use in AST nodes
%% Returns:
%%   {ok, AST} - where AST is the abstract syntax tree fragment, that returns the required field
%%               (if the field exists, and can be accessed from CxClass)
%%   {error, ErrorMessageText} - if the field does not exist, or can not be accessed from CxClass
field_accessor(Definition = {record, _, _}, FieldName, Expression, _, Line) ->
	records:field_accessor(Definition, FieldName, Expression, Line);
field_accessor(Definition = #class{}, FieldName, Expression, CxClass, Line) ->
	classes:field_accessor(Definition, FieldName, Expression, CxClass, Line).

%% Function: get_definition(Classes, Records, Name)
%% Purpose: looks up the definition of a class or record
%% Arguments:
%%   Classes::[#class{}] - list of known class definitions
%%   Records::[{record, Name, Fields}] - list of known record definitions
%%   Name::atom() - the name of class/record to look up
%% Returns:
%%      ClassDef::#class{} - if a definition of Name in Classes is found
%%      RecDef::{_,_,_} - if no class definition is found, but a definition of Name in Records is found
%%      notfound - if neither a class nor a record definition is found for Name
get_definition(Classes, Records, Name) ->
	case classes:lookup(Classes, Name) of
	ClassDef = #class{} ->
		ClassDef;
	notfound ->
		case records:lookup(Records, Name) of
		RecDef = {record, _, _} ->
			RecDef;
		notfound ->
			notfound
		end
	end.